

var INVALID_PAI = -1

var jiangs = [];
var chis = [];
var pengs = [];
var jiangPai = INVALID_PAI;   //一开始找将时的将牌
var curJiang = INVALID_PAI;   //无将由补牌得到的当前将牌
var caishenPaiCnt = 0;
var buPaiNum = caishenPaiCnt+1;
var anyHuPai = 34;
var jiangnum = 0;
var findShunziCnt = 0; //找可能的顺子组合计数
var countMapTmp = {};  //存放计算剩余牌集合
var buPaiSet = [];

var seatData = {
	//holds:[3,1,2,5,7,12,23,13,10,24,24,16,5],
	//holds:[1,1,1,3,3,3,5,5,5,24,24,24,17,17,17,18],
	holds:[7,5,6,5,6,7,1,10,9,18,18,18,2],
	//holds:[7,5,6,5,6,7,1,1,1,5,6,28,7],
	//holds:[7,5,6,5,6,7,1,1,1,8],
	//holds:[7,7,1,1],
	countMap:{},
	tingMap:{}
}

var nameMap = {
	[0]:'1筒',
	[1]:'2筒',
	[2]:'3筒',
	[3]:'4筒',
	[4]:'5筒',
	[5]:'6筒',
	[6]:'7筒',
	[7]:'8筒',
	[8]:'9筒',
	[9]:'1条',
	[10]:'2条',
	[11]:'3条',
	[12]:'4条',
	[13]:'5条',
	[14]:'6条',
	[15]:'7条',
	[16]:'8条',
	[17]:'9条',
	[18]:'1万',
	[19]:'2万',
	[20]:'3万',
	[21]:'4万',
	[22]:'5万',
	[23]:'6万',
	[24]:'7万',
	[25]:'8万',
	[26]:'9万',
	[27]:'红中',
	[28]:'发财',
	[29]:'白板',
	[30]:'东风',
	[31]:'南风',
	[32]:'西风',
	[33]:'北风',
}

var str = "";

//for (var i=0; i<34; ++i)
	//countMapTmp[i]=0;
for(var i = 0; i < seatData.holds.length; ++i){
	var pai = seatData.holds[i];
	if(seatData.countMap[pai] == null){
		seatData.countMap[pai] = 1;
	}
	else{
		seatData.countMap[pai] ++;
	}
	
	str += nameMap[pai];
}
//console.log(str);
//console.log(seatData.countMap);

//找出手牌可以做将的牌
function findJiangFromHolds(seatDataTmp)
{
	for (var key in seatDataTmp)
	{
		var pai = Number.parseInt(key);
		if (seatDataTmp[pai] >= 2 && !isAsJiangUse(pai))
		{
			jiangs.push(pai);
			seatDataTmp[pai] -= 2;
			jiangPai = pai;
			break;
		}
	}
	
	//jiangs.splice(0,jiangs.length);
	//jiangs.push(5);
	//seatDataTmp[5] -= 2;
	//jiangPai = INVALID_PAI;
}

//找出手牌可以当吃的牌
function findChiPaiFromHolds(seatData,minVal,maxVal)
{
	for (var i=0; i<seatData.holds.length; ++i)
	{
		var pai = seatData.holds[i];
		if (pai>=27) continue;
		if (pai<minVal || pai>=maxVal) continue;
		while (countMapTmp[pai]>0)
		{
			if (countMapTmp[pai]>0 && countMapTmp[pai+1]>0 && countMapTmp[pai+2]>0)
			{
				chis.push(pai);
				chis.push(pai+1);
				chis.push(pai+2);
				--countMapTmp[pai];
				--countMapTmp[pai+1];
				--countMapTmp[pai+2];
			}
			else if (countMapTmp[pai-1]>0 && countMapTmp[pai]>0 && countMapTmp[pai+1]>0)
			{
				chis.push(pai-1);
				chis.push(pai);
				chis.push(pai+1);
				--countMapTmp[pai-1];
				--countMapTmp[pai];
				--countMapTmp[pai+1];
			}
			else if (countMapTmp[pai-2]>0 && countMapTmp[pai-1]>0 && countMapTmp[pai]>0)
			{
				chis.push(pai-2);
				chis.push(pai-1);
				chis.push(pai);
				--countMapTmp[pai-2];
				--countMapTmp[pai-1];
				--countMapTmp[pai];
			}
			else
			{
				break;
			}
		}
	}
}

//找出手牌可以当碰的牌
function findPengPaiFromHolds()
{
	for (var key in countMapTmp)
	{
		var pai = Number.parseInt(key);
		if (countMapTmp[pai]>=3)
		{
			pengs.push(pai);
			countMapTmp[pai] = 0;
		}
	}
}

function checkCanTingPaiWithCaiShen(seatData)
{
	var seatDataTmp = {};
	
	//console.log(seatData.countMap);
	console.log("jiang num == "+ jiangnum);
	//打乱手牌
	for (var i=0; i<10; ++i)
	{
		//赋值
		for (var key in seatData.countMap)
		{
			var pai = Number.parseInt(key);
			if (seatData.countMap[pai] != undefined)
			{
				seatDataTmp[pai] = seatData.countMap[pai];
			}
		}
		//console.log(seatDataTmp);

		//找将
		jiangPai = INVALID_PAI;
		findJiangFromHolds(seatDataTmp);
		console.log("huan jiang");
		console.log("jiangpai is "+jiangPai);
		var loopNum = jiangPai != INVALID_PAI ? seatData.holds.length-2 : seatData.holds.length;
		loopNum = loopNum > 4 ? loopNum : 4;
		console.log("loop == "+loopNum);

		for (var j=0; j<loopNum/2; ++j)
		{
			//赋值, 选定了将
			for (var key in seatDataTmp)
			{
				var pai = Number.parseInt(key);
				if (seatDataTmp[pai] != undefined)
				{
					countMapTmp[pai] = seatDataTmp[pai];
				}
			}
			console.log(countMapTmp);

			//清空
			clear();

			//手牌洗牌
			seatData.holds.shuffle();
			//console.log("holds == "+seatData.holds);

			//随机吃碰
			if (j%2==0)
			{
				//找碰杠
				findPengPaiFromHolds();

				//找吃牌
				findChiPaiFromHolds(seatData,0,9);
				findChiPaiFromHolds(seatData,9,18);
				findChiPaiFromHolds(seatData,18,27);
			}
			else
			{
				//找顺子
				findChiPaiFromHolds(seatData,0,9);
				findChiPaiFromHolds(seatData,9,18);
				findChiPaiFromHolds(seatData,18,27);

				//找豹子
				findPengPaiFromHolds();
			}

			//打印
			console.log("jiang: "+jiangPai+"  chi: "+chis+"  peng: "+pengs+"  hold: "+seatData.holds);
			console.log(countMapTmp);

			//剩余牌数
			var lestNum = 0;
			for (var key in countMapTmp)
			{
				var pai = Number.parseInt(key);
				if (countMapTmp[pai]>0)
				{
					lestNum += countMapTmp[pai];
				}
			}

			//是否听牌(补牌)
			var resultMap = {};
			for (var k=0; k<lestNum; ++k)
			{
				//找剩余牌开始补牌
				buPaiNum = caishenPaiCnt+1; //buPaiNum为补牌次数

				//当前将牌
				curJiang = jiangPai;

				for (var k in countMapTmp)
				{
					var pai = Number.parseInt(k);
					if (countMapTmp[pai]>0)
					{
						resultMap[pai] = countMapTmp[pai];
					}
				}

				var bHu = false;
				if (k%2==0)
				{
					bHu = calTingResult(0,9);
					bHu = bHu || calTingResult(9,18);
					bHu = bHu || calTingResult(18,27);
					bHu = bHu || calTingResult(27,34);				
				}
				else
				{
					bHu = calTingResult(27,34);
					bHu = bHu || calTingResult(18,27);
					bHu = bHu || calTingResult(9,18);
					bHu = bHu || calTingResult(0,9);
				}

				//如果胡牌了,将补牌集合的牌放入听牌集合
				if (bHu)
				{
					console.log("hu pai la , kuai la ya");
					for (var k2=0; k2<buPaiSet.length; ++k2)
					{
						if (seatData.tingMap[buPaiSet[k2]]==undefined || seatData.tingMap[buPaiSet[k2]]<=0)
						{
							seatData.tingMap[buPaiSet[k2]]=true;
						}
					}
					buPaiSet.splice(0,buPaiSet.length);
				}
				else
				{
					buPaiSet.splice(0,buPaiSet.length);
				}

				//还原
				if (k<lestNum-1)
				{
					for (var k in resultMap)
					{
						var pai = Number.parseInt(k);
						if (resultMap[pai]>0)
						{
							countMapTmp[pai] = resultMap[pai];
						}
					}
				}
			}
			
			//还原吃碰杠
			//console.log("after result is ");
			//console.log(countMapTmp);
		}
	}
}

//清空
function clear()
{
	chis.splice(0,chis.length);
	pengs.splice(0,pengs.length);
}

//是否听牌
function calTingResult(minVal,maxVal)
{
	//统计剩余牌
	var lestPai = [];

	//放入原始剩余数据
	for (var key in countMapTmp)
	{
		var pai = Number.parseInt(key);
		for (var i=0; i<countMapTmp[pai]; ++i)
		{
			lestPai.push(pai);
		}
	}

	console.log("lest pai is "+lestPai);
	//console.log(countMapTmp);
	if (lestPai.length<=0)
	{
		console.log("data is not in this round!");
		return;
	}

	//乱序
	lestPai.shuffle();
	console.log("lest pai shuffle : "+lestPai);

	for (var l=0; l<lestPai.length; ++l)
	{
		//暂存将
		//console.log("jiangPai == "+jiangPai+" curJiang == "+ curJiang);

		//开始补牌
		var pai = lestPai[l%lestPai.length];
		if (countMapTmp[pai]==undefined || countMapTmp[pai]<=0)
		{
			continue;
		}
		if (pai<minVal || pai>=maxVal)
		{
			continue;
		}
		
		//先补将还是补牌
		var bJiangPriority = false; 
		if (Math.floor(Math.random() * 10) < 5)
		{
			bJiangPriority = true;
		}
		if (curJiang==INVALID_PAI && bJiangPriority)
		{
			console.log("begin to bu jiang");
			//补将
			if (buJiang(pai,minVal,maxVal))
			{
				console.log("bu jiang, pai is " + pai);
				return true;
			}
			else if (buPai(pai,minVal,maxVal,lestPai.length))
			{
				console.log("bu pai, pai is " + pai);
				return true;
			}
		}
		else if (curJiang==INVALID_PAI && !bJiangPriority)
		{
			console.log("begin to bu pai");
			//补牌
			if (buPai(pai,minVal,maxVal,lestPai.length))
			{
				console.log("bu pai, pai is " + pai);
				return true;
			}
			else if (buJiang(pai,minVal,maxVal)) //补将
			{
				console.log("bu jiang, pai is " + pai);
				return true;
			}
		}
		else
		{
			//补牌
			if (buPai(pai,minVal,maxVal,lestPai.length))
			{
				console.log("bu pai, pai is " + pai);
				return true;
			}
		}
	}
}

//补将
function buJiang(pai,minVal,maxVal)
{
	console.log("curJiang == "+curJiang+" pai == "+pai+" countMapTmp == "+countMapTmp[pai]+" buPaiNum == "+ buPaiNum);
	if (curJiang<0 && countMapTmp[pai]==1 && buPaiNum>0)
	{
		console.log("bu jiang: " + pai);
		--countMapTmp[pai];
		console.log(countMapTmp);
		curJiang = pai;
		jiangs.push(pai);
		return isTingByPaiNum(pai);
	}
	return false;
}

//补牌
function buPai(pai,minVal,maxVal,lestPaiNum)
{
	var bHu = false;
    for (var j=0; j<lestPaiNum+3; ++j) 
    {
		if (buPaiNum<=0)
		{
			break;
		}
		if (j%2==1)
        {
            //补顺子
            if (pai<27)
			{
				if (fillShunZi(pai,minVal,maxVal,lestPaiNum))
				{
					console.log("hu: fill shun zi, pai is "+pai);
					bHu = true;
					break;
				}
			}
                
            //补豹子
			if (fillBaoZi(pai,lestPaiNum))
			{
				console.log("hu: fill bao zi, pai is "+pai);
				bHu = true;
				break;
			}
			//console.log("bu shunzi , bu baozi buPaiNum == "+buPaiNum);
        }
        else
        {
            //补豹子
			if (fillBaoZi(pai,lestPaiNum))
			{
				console.log("hu: fill bao zi, pai is "+pai);
				bHu = true;
				break;
			}
			//console.log("bu baozi , buPaiNum == "+buPaiNum);

            //补顺子
            if (pai<27)
			{
				if (fillShunZi(pai,minVal,maxVal,lestPaiNum))
				{
					console.log("hu: fill shun zi, pai is "+pai);
					bHu = true;
					break;
				}
			}
			//console.log("bu baozi , bu shunzi buPaiNum == "+buPaiNum);
        }
    }

	return bHu;
}

function fillShunZi(pai,minVal,maxVal,lestPaiNum)
{	
	if (buPaiNum<=0 || lestPaiNum<=0)
	{
		return false;
	}

	//补牌次数大于1,且剩余牌只有1张时
	/*
	if (buPaiNum>1 && lestPaiNum==1)
	{
		console.log("1 pai == "+pai+" countMapTmp num == "+ countMapTmp[pai]);
		var daPaiType = Math.random()*4;
		switch (daPaiType) 
		{
			case 0:
			{
				if (pai+1<maxVal && countMapTmp[pai]>0 && countMapTmp[pai+1]<0)
				{
					countMapTmp[pai+1]=1;
					--buPaiNum;
				}
			}
			break;
			case 1:
			{
				if (pai-1>minVal && countMapTmp[pai]>0 && countMapTmp[pai-1]<0)
				{
					countMapTmp[pai-1]=1;
					--buPaiNum;
				}
			}
			break;
			case 2:
			{
				if (pai+2>maxVal && countMapTmp[pai]>0 && countMapTmp[pai+2]<0)
				{
					countMapTmp[pai+2]=1;
					--buPaiNum;
				}
			}
			break;
			case 3:
			{
				if (pai-2>minVal && countMapTmp[pai]>0 && countMapTmp[pai-2]<0)
				{
					countMapTmp[pai-2]=1;
					--buPaiNum;
				}
			}
			break;
			default:
				break;
		}
		return false;
	}*/
	//补顺子
	var bHu = false;
	//console.log("findShunziCnt == "+findShunziCnt);
	if (findShunziCnt==0)
	{
		//console.log("cur pai is "+pai+"paiAdd");
		bHu = paiAdd(pai,minVal,maxVal);
		bHu = bHu || paiSub(pai,minVal,maxVal);
		bHu = bHu || paiAddSub(pai,minVal,maxVal);
		++findShunziCnt;
	}
	else if (findShunziCnt==1)
	{
		//console.log("cur pai is "+pai+"paiSub");
		bHu = paiSub(pai,minVal,maxVal);
		bHu = bHu || paiAddSub(pai,minVal,maxVal);
		bHu = bHu || paiAdd(pai,minVal,maxVal);
		++findShunziCnt;
	}
	else
	{
		//console.log("cur pai is "+pai+"paiAddSub");
		bHu = paiAddSub(pai,minVal,maxVal);
		bHu = bHu || paiAdd(pai,minVal,maxVal);
		bHu = bHu || paiSub(pai,minVal,maxVal);
		if (findShunziCnt==2)
		{
			findShunziCnt=0;
		}
	}

	//console.log("2 pai == "+pai+"countMapTmp num == "+ countMapTmp[pai]);
	return bHu;
}

function paiAdd(pai,minVal,maxVal)
{
	//console.log(countMapTmp);
	//console.log("paiAdd countMapTmp[pai] == "+countMapTmp[pai]+ "countMapTmp[pai+1] == "+countMapTmp[pai+1]);
	if (pai+2<maxVal && countMapTmp[pai]>0 && countMapTmp[pai+1]>0)
	{
		if (!isTinged(pai+2))
		{
			--countMapTmp[pai];
			--countMapTmp[pai+1];
			console.log("que pai+2 pai == ", pai);
			return isTingByPaiNum(pai+2);	
		}
	}
	else if (pai+2<maxVal && countMapTmp[pai]>0 && countMapTmp[pai+2]>0)
	{
		if (!isTinged(pai+1))
		{
			--countMapTmp[pai];
			--countMapTmp[pai+2];
			console.log("enter pai+1 pai == ", pai);
			return isTingByPaiNum(pai+1);
		}
	}
	return false;
}

function paiAddSub(pai,minVal,maxVal)
{
	//console.log("paiAddSub minVal == "+ minVal+" maxVal == "+maxVal);
	//console.log("paiAddSub pai ==  "+pai+" countMapTmp[pai] == "+countMapTmp[pai]+ "countMapTmp[pai+1] == "+countMapTmp[pai+1]);
	if (pai-1>=minVal && pai+1<maxVal && countMapTmp[pai]>0 && countMapTmp[pai+1]>0)
	{
		if (!isTinged(pai-1))
		{
			--countMapTmp[pai];
			--countMapTmp[pai+1];
			--buPaiNum;
			console.log("que pai-1 pai == ", pai);
			return isTingByPaiNum(pai-1);
		}
	}
	else if (pai-1>=minVal && pai+1<maxVal && countMapTmp[pai]>0 && countMapTmp[pai-1]>0)
	{
		if (!isTinged(pai+1))
		{
			--countMapTmp[pai];
			--countMapTmp[pai-1];
			console.log("que pai+1 pai == ", pai);
			return isTingByPaiNum(pai+1);
		}
	}
	return false;
}

function paiSub(pai,minVal,maxVal)
{
	if (pai-2>minVal && countMapTmp[pai]>0 && countMapTmp[pai-1]>0)
	{
		if (isTinged(pai-2))
		{
			--countMapTmp[pai];
			--countMapTmp[pai-1];
			console.log("que pai-2 pai == ", pai);
			return isTingByPaiNum(pai-2);
		}
	}
	else if (pai-2>minVal && countMapTmp[pai]>0 && countMapTmp[pai-2]>0)
	{
		if (isTinged(pai-1))
		{
			--countMapTmp[pai];
			--countMapTmp[pai-2];
			console.log("que pai-1 pai == ", pai);
			return isTingByPaiNum(pai-1);
		}
	}
	return false;
}

function isTingByPaiNum(pai)
{
	if (buPaiNum<=0)
	{
		return;
	}
	--buPaiNum;
	buPaiSet.push(pai);
	console.log("isTingByPaiNum buPaiNum == "+buPaiNum);
	console.log(countMapTmp);
	if (!isHasPai())
	{
		if (0==buPaiNum)
		{
			seatData.tingMap[pai] = true;
		}
		else
		{
			seatData.tingMap[anyHuPai] = true;
		}
		console.log("ting pai buPaiNum == "+buPaiNum);

		return true;
	}
	return false;
}

//补豹子
function fillBaoZi(pai,lestPaiNum)
{
	if (buPaiNum<=0)
	{
		return false;
	}

	if (countMapTmp[pai]==2)
	{
		console.log("fill bao zi is " + pai + " pai num is " + countMapTmp[pai]);
		countMapTmp[pai]-=2;
		console.log(countMapTmp);
		return isTingByPaiNum(pai);
	}
	//else if (lestPaiNum==1 && countMapTmp[pai]==1)
	{
		//countMapTmp[pai]+=1;
		//--buPaiNum;
		//console.log("bao zi add 1 pai == "+pai+" pai num == "+countMapTmp[pai]);
	}

	return false;
}


//是否还有牌
function isHasPai()
{
	for (var key in countMapTmp)
	{
		var pai = Number.parseInt(key);
		if (countMapTmp[pai]>0)
		{
			return true;
		}
	}
	return false;
}


//牌是否曾作为将
function isAsJiangUse(pai)
{
	for (var i=0; i<jiangs.length; ++i)
	{
		if (pai==jiangs[i])
		{
			return true;
		}
	}
	return false;
}

//该牌是否已听牌
function isTinged(pai)
{
	for (var key in countMapTmp)
	{
		var paiTmp = Number.parseInt(key);
		if (paiTmp==pai)
		{
			return true;
		}
	}
	return false;
}


//手牌洗牌
if (!Array.prototype.shuffle) 
{
    Array.prototype.shuffle = function() 
	{
		for (var j=0,x=0,i=this.length-1;i>0;--i)
		{
			j = parseInt(Math.random() * (i+1));
			x = this[i];
			this[i] = this[j];
			this[j] = x;
		}
        return this;
    };
}


for (var key in seatData.countMap)
{
	var pai = Number.parseInt(key);
	if (seatData.countMap[pai]>=2)
	{
		++jiangnum;
	}
}

//for (var i=0; i<jiangnum+1; ++i)
{
	//检查是否听牌
	//checkCanTingPaiWithCaiShen(seatData);
}

//console.log(seatData.countMap);

//console.log("听牌结果如下:");
//for(var k in seatData.tingMap)
{
	//console.log("牌值 = "+ k + " 牌名称 = " + nameMap[k]);
}
